//
//  RSAUtil.m
//  WHTest
//
//  Created by shengmeng chen on 2019/5/18.
//  Copyright © 2019 shengmeng chen. All rights reserved.
//

#import "RSAUtil.h"

#define MODULUS "D531DB1339392D32D2273E186BEDA7178BB20C0169D1B8106A83480B8ADD71721513865858A5E236E3F68D6DDFBD52CB9984E49DB7C4F5B86789AAC5B2C0BC67A02A2DE6823EFA5CE05A6DF7190C383893996C80D78A8121C07ED02B85181788EE3D4B127503FC0CFFAA336B271ACF0DCC92E324F4473C14D6A0EBAEE863C035"

#define PUBLIC_EXPONENT 65537

@implementation RSAUtil
+(void)encrypt
{
    int ret, flen;
    BIGNUM *bnn, *bne;
    //,*bnd
    
    bnn = BN_new();
    bne = BN_new();
    //bnd = BN_new();
    
    BN_hex2bn(&bnn, MODULUS);
    BN_set_word(bne, PUBLIC_EXPONENT);
    //BN_hex2bn(&bnd, MODULUS);
    
    RSA *r = RSA_new();
    //RSA* r = RSA_generate_key( 2048 ,RSA_F4,0,0);
    
    r->e = bne;
    r->n = bnn;
    //r->d = bnd;
    
    RSA_print_fp(stdout, r, 5);
    
    flen = RSA_size(r) - 11;// - 11;
    
    /*out = (char *)malloc(flen);
     bzero(out, flen);*/
    //memset(out, 0, flen);
    
    char *sp = (char *)malloc(flen);
    bzero(sp, flen);
    //memset(sp, 0, flen);
    
    char *message = "4170438028591BFC";
    
    BIGNUM *rs;
    
    rs = BN_new();
    
    ret = RSA_public_encrypt(flen, (unsigned char *)message  , (unsigned char *)sp, r, RSA_PKCS1_PADDING);
    
    if (ret > 0)
    {
        //BN_bin2bn((unsigned char *)sp, flen, rs);
        //NSLog(@"Encrypt OK, sp=%s",BN_bn2hex(rs));//转为16进制
        unsigned  char *tmpData;
        
        tmpData=(unsigned char *)sp;
        
        for  (int i=0; i<ret; i++){
            printf("%02X", *tmpData);
            tmpData++;
        }
        //BN_bin2bn((unsigned char *)sp, flen, rs);
        //NSLog(@"Encrypt OK, sp=%s",BN_bn2hex(rs));//转为16进制
    }else{
        NSLog(@"%d",ret);
    }
    
    RSA_free(r);
    
    printf("\n");
}

+(int)test
{
    
    char userkey[AES_BLOCK_SIZE];
    unsigned char *date = malloc(AES_BLOCK_SIZE*3);
    unsigned char *encrypt = malloc(AES_BLOCK_SIZE*3 + 4);
    unsigned char *plain = malloc(AES_BLOCK_SIZE*3);
    AES_KEY key;
    
    memset((void*)userkey, 'k', AES_BLOCK_SIZE);
    memset((void*)date, 'p', AES_BLOCK_SIZE*3);
    memset((void*)encrypt, 0, AES_BLOCK_SIZE*6);
    memset((void*)plain, 0, AES_BLOCK_SIZE*3);
    
    /*设置加密key及密钥长度*/
    AES_set_encrypt_key(userkey, AES_BLOCK_SIZE*8, &key);
    
    int len = 0;
    /*循环加密，每次只能加密AES_BLOCK_SIZE长度的数据*/
    while(len < AES_BLOCK_SIZE*3) {
        AES_encrypt(date+len, encrypt+len, &key);
        len += AES_BLOCK_SIZE;
    }
    /*设置解密key及密钥长度*/
    AES_set_decrypt_key(userkey, AES_BLOCK_SIZE*8, &key);
    
    len = 0;
    /*循环解密*/
    while(len < AES_BLOCK_SIZE*3) {
        AES_decrypt(encrypt+len, plain+len, &key);
        len += AES_BLOCK_SIZE;
    }
    /*解密后与原数据是否一致*/
    if(!memcmp(plain, date, AES_BLOCK_SIZE*3)){
        printf("test success\n");
    }else{
        printf("test failed\n");
    }
    
    printf("encrypt: ");
    int i = 0;
    for(i = 0; i < AES_BLOCK_SIZE*3 + 4; i++){
        printf("%.2x ", encrypt[i]);
        if((i+1) % 32 == 0){
            printf("\n");
        }
    }
    printf("\n");
    
    return 0;
}
@end
